package com.xiaoge.auth.security.component;

import com.xiaoge.system.entity.Menu;
import com.xiaoge.system.entity.Role;
import com.xiaoge.system.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

/**
 * 权限控制
 * 根据请求url分析请求所需的角色
 *
 * @author zhoubin
 * @since 1.0.0
 */
@Component
public class CustomMetadataSource implements FilterInvocationSecurityMetadataSource {

	@Autowired
	private MenuService menuService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

	private AntPathMatcher antPathMatcher = new AntPathMatcher();

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		//获取请求的url
		String requestUrl = ((FilterInvocation) object).getRequestUrl();
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        //redis中获取菜单权限数据
        List<Menu> menus = (List<Menu>) valueOperations.get("menus_role" );
        //如果没有就从数据库中获取
        if (CollectionUtils.isEmpty(menus)){
            menus=menuService.getMenusWithRole();
            valueOperations.set("menus_role",menus);
        }
		for (Menu menu : menus) {
			//判断请求url与菜单角色是否匹配
			if (menu.getPerms()!=null&&antPathMatcher.match(menu.getPerms(),requestUrl)){
				String[] str = menu.getRoles().stream().map(Role::getRoleName).toArray(String[]::new);
				return SecurityConfig.createList(str);
			}
		}
		//没匹配的url默认登录即可访问
		return SecurityConfig.createList("ROLE_LOGIN");
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}
}